package com.example.routelink.gateway.filter;


import cn.dev33.satoken.config.SaSignConfig;
import cn.dev33.satoken.sign.SaSignTemplate;
import com.example.routelink.gateway.entity.ResultEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class SignatureFilterGatewayFilterFactory extends BaseFilter<SignatureFilterGatewayFilterFactory.Config> implements Ordered {
    public SignatureFilterGatewayFilterFactory() {
        super(Config.class);
    }

    private final String filterName = "验证签名";

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            long startTime = System.currentTimeMillis();
            SaSignConfig saSignConfig = new SaSignConfig();
            saSignConfig.setSecretKey(config.getSecretKey());
            saSignConfig.setTimestampDisparity(3 * 60 * 1000);
            SaSignTemplate saSignTemplate = new SaSignTemplate(saSignConfig);
            Map<String, String> queryParams = exchange.getRequest().getQueryParams().toSingleValueMap();
            Map<String, String> queryParams2 = new HashMap<>();
            for (Map.Entry<String, String> entry : queryParams.entrySet()) {
                if (!isGatewayCustom(entry.getKey())) {
                    queryParams2.put(entry.getKey(), entry.getValue());
                }
            }
            boolean result = saSignTemplate.isValidParamMap(queryParams2);

            if (!result) {
                writeLog(filterName, startTime, "校验失败");
                return response(exchange, ResultEnum.ErrSignature);
            }
            writeLog(filterName, startTime, "校验通过");
            return chain.filter(exchange);
        };
    }

    @Data
    public static class Config {
        private String secretKey;
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


}
